package top.hmtools.autoConfiguration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;

import top.hmtools.common.StaticContent;

/**
 * 线程池配置
 * @author HyboJ
 *
 */
@Configuration
@ConditionalOnProperty(prefix=StaticContent.CONFIG_PREFIX,value=StaticContent.CONFIG_ITEM_KEY_NAME_ENABLED,matchIfMissing=true)
public class ThreadPoolConfiguration {
	
	protected final Logger logger = LoggerFactory.getLogger(ThreadPoolConfiguration.class);
	
	/**
	 * 线程池维护线程的最少数量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_CORE_SIZE+":5}")
	private int poolCoreSize;
	
	/**
	 * 线程池维护线程的最大数量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_MAX_SIZE+":52}")
	private int poolMaxSize;
	
	/**
	 *  线程池所使用的缓冲队列容量
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_WORK_QUEUE_SIZE+":100}")
	private int poolWorkQueueSize;
	
	/**
	 * 线程池维护线程所允许的空闲时间
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_KEEP_ALIVE_TIME+":60}")
	private int poolKeepAliveTime;
	
	/**
	 * 线程池维护线程所允许的空闲时间的单位：NANOSECONDS，MICROSECONDS，MILLISECONDS，SECONDS，MINUTES，HOURS，DAYS
	 */
	@Value("${"+StaticContent.CONFIG_PREFIX+"."+StaticContent.CONFIG_ITEM_KEY_NAME_POOL_KEEP_ALIVE_TIME_UNIT+":SECONDS}")
	private String poolKeepAliveTimeUnit;

	/**
	 * 构造一个线程池
	 * <br> corePoolSize： 线程池维护线程的最少数量
	 * <br> maximumPoolSize：线程池维护线程的最大数量
	 * <br>keepAliveTime： 线程池维护线程所允许的空闲时间 
	 * <br>unit： 线程池维护线程所允许的空闲时间的单位
	 * <br>workQueue： 线程池所使用的缓冲队列 
	 * <br>handler： 线程池对拒绝任务的处理策略
	 */
	@Bean("rl_threadPoolExecutor")
	@Scope("singleton")
	@Order(10)
	public ThreadPoolExecutor rl_threadPoolExecutor(){
		String poolKeepAliveTimeUnit = this.poolKeepAliveTimeUnit;
		TimeUnit timeUnit = TimeUnit.valueOf(poolKeepAliveTimeUnit.trim().toUpperCase());
		timeUnit = timeUnit == null?TimeUnit.SECONDS:timeUnit;
		ThreadPoolExecutor result = new ThreadPoolExecutor(
				this.poolCoreSize, 
				this.poolMaxSize,
				this.poolKeepAliveTime, 
				timeUnit,
				new ArrayBlockingQueue<Runnable>(this.poolWorkQueueSize),
				new ThreadPoolExecutor.DiscardOldestPolicy());
		logger.info("初始化线程池成功。。。");
		return result;
	}
}
